package game.leon.war.node.service;

import game.leon.engine.letter.PostOffice;
import game.leon.engine.net.codec.GateRawMessage;
import game.leon.engine.utils.LinkedNode;
import game.leon.engine.utils.Reciever;
import game.leon.war.node.handler.HandlerService;
import game.leon.war.node.handler.letter.NodeLetter;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 消息分发服务
 * User: bianpeng
 * Date: 12-2-8
 */
@Component
public class MessageDispatcher {
    private Logger logger = Logger.getLogger(getClass());
    private ExecutorService executorService = Executors.newSingleThreadExecutor();
    private Reciever<GateRawMessage> gateRawMessageReciever = new Reciever<GateRawMessage>();
    private PostOffice<NodeLetter> postOffice = new PostOffice<NodeLetter>();
    @Autowired
    private HandlerService handlerService;
    @PostConstruct
    public void init() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                for(;;) {
                    LinkedNode<GateRawMessage> message = gateRawMessageReciever.consume();
                    while (message != null) {
                        executorService.execute(new GateRawMessageRun(message.getItem()));
                        message = message.getNext();
                    }
                    LinkedNode<NodeLetter> letter = postOffice.expire();
                    while (letter != null) {
                        executorService.execute(new NodeLetterRun(letter.getItem()));
                        letter = letter.getNext();
                    }
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        logger.warn("dispatch wait interrupted");
                    }
                }
            }
        }).start();
    }
    private class NodeLetterRun implements Runnable {
        private NodeLetter letter;
        public NodeLetterRun(NodeLetter letter) {
            this.letter = letter;
        }
        @Override
        public void run() {
            handlerService.handle(letter);
        }
    }
    private class GateRawMessageRun implements Runnable {
        private GateRawMessage message;
        public GateRawMessageRun(GateRawMessage message) {
            this.message = message;
        }
        @Override
        public void run() {
            handlerService.handle(message);
        }
    }
    //
    // 网络消息
    //
    public void dispatch(GateRawMessage message) {
        gateRawMessageReciever.recieve(message);
    }
    //
    // 延时消息
    //
    public void dispatch(NodeLetter message) {
        postOffice.post(message);
    }
}
